#include <stdio.h>
#include <string.h>
#include <assert.h>
#include <errno.h>
// #include <stdio.h>

//  库函数strcat追加字符串
//  目标空间必须足够大，还需要可以修改
//  目标空间必须有\0，保证能找到目标空间的末尾
//  源字符串中也要有\0，在拷贝时将源字符串中的\0也要拷贝过去

// 这种情况不能自己追加自己，自己的\0被覆盖
char *My_strcat(char *dest, const char *src)
{
    assert(dest && src);
    char *head = dest;
    while (*dest != '\0')
    {
        dest++;
    }
    while (*src != '\0')
    {
        *dest++ = *src++;
    }
    *dest = '\0';

    return head;
}

// int main()
// {
//     char arr1[20] = "abc";
//     char arr2[] = "def";
//     My_strcat(arr1, arr2);
//     printf("%s\n", arr1);
//     return 0;
// }

// 库函数strcmp字符串比较
// 不是比较长度，而是比较对应位置上字符的大小 ASCII的值
// 返回值：大于返回大于1的数字，等于返回0，小于返回小于1的数字

// int main()
// {
//     char arr1[] = "abcdef";
//     char arr2[] = "abq";
//     int ret = strcmp(arr1, arr2);
//     printf("%d\n", ret);
//     return 0;
// }

// 模拟实现strcmp
int My_strcmp(const char *str1, const char *str2)
{
    assert(str1 && str2);
    while (*str1 == *str2)
    {
        if (*str1 == '\0')
        {
            return 0;
        }
        ++str1;
        ++str2;
    }
    if (*str1 > *str2)
    {
        return 1;
    }
    else
    {
        return -1;
    }
}

// int main()
// {
//     char arr1[] = "abqc";
//     char arr2[] = "abq";
//     int ret = My_strcmp(arr1, arr2);
//     printf("%d\n", ret);
//     return 0;
// }

// 库函数strncpy，可以控制拷贝几个字符
// 但是，不是自动拷贝\0，这点和strcpy时不一样的
// 如果要求拷贝的字符数大于arr2中的字符数，那么不够的字符会被替换成\0进行靠背

// strncpy的模拟实现
// char * strncpy ( char * destination, const char * source, size_t num )

char *My_strncpy(char *dest, const char *src, size_t num)
{
    assert(dest && src);
    char *start = dest;               // 记录目标数组首地址
    while (num && (*dest++ = *src++)) // 复制字符串，并考虑n小于或等于被拷贝字符串数目的情况
    {
        num--;
    }
    if (num) // 如果n大于被拷贝字符串数目，须将除被拷贝字符的其他内容用空字符进行补充
    {
        while (num)
        {
            *dest++ = '\0';
            num--;
        }
    }
    return start;
}

// int main()
// {
//     char arr1[20] = "**********";
//     char arr2[] = "hello";
//     // strncpy(arr1, arr2, 5);
//     My_strncpy(arr1, arr2, 5);
//     printf("%s\n", arr1);
//     return 0;
// }

// strstr库函数，返回str1中str2第一次出现的位置
// 如果str1中没有str2，就返回NULL

// strstr模拟实现
const char *My_strstr(const char *str1, const char *str2)
{
    assert(str1 && str2);
    if (*str2 == '\0')
    {
        return str1;
    }
    const char *cp; // 记录开始匹配的位置
    const char *s1; // 遍历str1指向的字符串
    const char *s2; // 遍历str2指向的字符串

    cp = str1;
    while (*cp)
    {
        s1 = cp;
        s2 = str2;
        while (*s1 && s2 && *s1 == *s2)
        {
            s1++;
            s2++;
        }
        if (*s2 == '\0')
        {
            return cp;
        }
        cp++;
    }
    return NULL;
}
// int main()
// {
//     char str1[] = "abcdefghi";
//     char str2[] = "adef";
//     // char *ret = strstr(str1, str2);
//     const char *ret = My_strstr(str1, str2);
//     if (ret == NULL)
//     {
//         printf("找不到\n");
//     }
//     else
//     {
//         printf("%s\n", ret);
//     }
//     return 0;
// }

// 库函数strtok 切割字符串

// int main()
// {
//     char arr[] = "wquanhao@gmail.com";
//     char arr2[100] = "192.168.0.1";
//     char buf[50] = {0};
//     char buf2[50] = {0};
//     char *p = "@.";
//     char *p2 = ".";
//     char *s = NULL;
//     strcpy(buf, arr);
//     strcpy(buf2, arr2);
//     // char *s = strtok(buf, p);
//     // printf("%s\n", s);
//     // s = strtok(NULL, p);
//     // printf("%s\n", s);
//     // s = strtok(NULL, p);
//     // printf("%s\n", s);
//     for (s = strtok(buf, p); s != NULL; s = strtok(NULL, p))
//     {
//         printf("%s\n", s);
//     }
//     for (s = strtok(buf2, p2); s != NULL; s = strtok(NULL, p2))
//     {
//         printf("%s\n", s);
//     }
//     return 0;
// }

// int main()
// {
//     int i = 0;
//     for (i = 0; i < 10; i++)
//     {
//         printf("%d: %s\n", i, strerror(i));
//     }
//     return 0;
// }

// 打开文件的例子
// fopen以读的形式打开文件
// 如果文件存在，打开成功
// 如果文件不存在，打开失败

int main()
{
    FILE *pf = fopen("add.txt", "r");
    if (pf == NULL)
    {
        printf("打开文件夹失败，原因是:%s\n", strerror(errno));
        perror("打开文件失败");
        return 1;
    }
    else
    {
        printf("打开文件成功\n");
    }
    return 0;
}
//perror直接打印错误码，所对应的错误信息
//perror == printf + strerror
//perror中打印的时候，规则：自定义信息：XXXXXXXXXXX